package controller

import (
	"time"

	. "gddgame.cc/galaxy/common/dsl/web"
	"gddgame.cc/galaxy/core/models"
	"gddgame.cc/galaxy/utils"
	"gddgame.cc/galaxy/utils/uuid"

	"gddgame.cc/galaxy/utils/def"
)

func Login(context def.Context, app *models.App, username string, password string) (*models.UserOpen, error) {
	var user models.User
	var userOpen models.UserOpen
	if ok, err := models.UserModel.Query().Where("=", "name", username).One(&user); !ok {
		return nil, EmptyExceptionDetail("ACCOUNT_EMPTY", err)
	}

	if user.FormatPassword(password) != user.Password {
		return nil, ValidException("PASSWORD_WRONG")
	}
	if ok, _ := models.UserOpenModel.Query().
		Where("=", "app_id", app.Id).
		Where("=", "user_id", user.Id).One(&userOpen); !ok {
		// 添加对应应用的账号
		userOpen = models.UserOpen{
			Id:       app.EncodeUser(user.Id),
			UserId:   user.Id,
			AppId:    app.Id,
			NickName: "",
			Avatar:   "",
			Token:    uuid.RandomString(),
		}
		if _, err := models.UserOpenModel.Insert(userOpen); err != nil {
			return nil, SystemExceptionDetail("用户添加失败", err)
		}
	} else {
		// 如果单点登录，需要更新该用户的token
		userOpen.Token = uuid.RandomString()

		if err := UpdateOpen(context, app, userOpen.Id, map[string]interface{}{
			"token":     userOpen.Token,
			"last_time": time.Now(),
		}); err != nil {
			return nil, err
		}
	}

	return &userOpen, nil
}

func ValidToken(context def.Context, app *models.App, token string) (*models.UserOpen, error) {
	var userOpen models.UserOpen
	var err error
	var ok bool
	if ok, err = models.UserOpenModel.Query().Where("=", "app_id", app.Id).Where("=", "token", token).One(&userOpen); !ok {
		return nil, EmptyExceptionDetail("ACCOUNT_EMPTY", err)
	}
	err = UpdateOpen(context, app, userOpen.Id, map[string]interface{}{
		"last_time": time.Now(),
	})

	return &userOpen, err
}

func RegisterGuest(context def.Context, app *models.App) (*models.UserOpen, error) {
	user := models.User{
		GuestId:  utils.ToString(time.Now().Nanosecond()),
		Name:     "",
		Password: "",
		Email:    "",
		Mobile:   "",
	}
	if _, err := models.UserModel.Insert(&user); err != nil {
		return nil, SystemExceptionDetail("用户添加失败", err)
	}
	userOpen := models.UserOpen{
		Id:       app.EncodeUser(user.Id),
		UserId:   user.Id,
		AppId:    app.Id,
		NickName: "Guest" + utils.ToString(user.Id),
		Avatar:   "",
		Token:    uuid.RandomString(),
	}
	if _, err := models.UserOpenModel.Insert(&userOpen); err != nil {
		return nil, SystemExceptionDetail("用户添加失败", err)
	}

	return &userOpen, nil
}

func GetUser(context def.Context, userId int) (*models.User, error) {
	var user models.User
	var err error
	var ok bool
	err = wrap.Cache("user/"+utils.ToString(userId), &user, func() error {
		if ok, err = models.UserModel.PK(userId).One(&user); !ok {
			return EmptyExceptionDetail("用户不存在", err)
		}
		return nil
	})

	return &user, err
}

func UpdateUser(context def.Context, userId int, data map[string]interface{}) error {
	return wrap.SingleClean("user/"+utils.ToString(userId), func() error {
		if _, err := models.UserModel.PK(userId).Update(data); err != nil {
			return SystemExceptionDetail("更新用户失败", err)
		}
		return nil
	}, false)
}
